#include "public_def.h"

#include "rtspser.h"
#include "rtspserver.h"
#include "arrayctrl.h"
#include "rtspwatchdog.h"
#include "utils.h"

static pthread_t wdThread;
static bool blWDIsRunning = true;

//Disconnect RTSP connection
//
//Parameter:
//	conn 			RTSP connection
//
//Return:
//	None
//
void WDDisconnectRTSPConnection(RTSPConnection_t * conn)
{
	if (conn)
	{
		dbgprintf(0, "%s %d exit", __func__, __LINE__);
        if (!conn->rtspSock.m_blExitFlg)
        {
            conn->rtspSock.m_blExitFlg = 1;
        }
	}
}

//Print connection status (private, just for test)
//
//Parameter:
//	None
//Return:
//	None
//
void _printAllConnections()
{
	int i, cnt;
	RTSPConnection_t *conn;
	cnt = AC_Count(g_ptRTSPServer->listRTSPConnection);
	dbgprintf(0, "Connection status report");
	for(i = 0; i < cnt; i++)
	{
		conn = AC_Get(g_ptRTSPServer->listRTSPConnection, i);
		if (conn)
		{
			dbgprintf(0, "Connection status %d/%d", i + 1, cnt);
			dbgprintf(0, "Connection status %s, CH #%d", conn->remoteip, conn->chID);
			dbgprintf(0, "Connection status active = %d", conn->active);
		}
	}
}

//Monitor thread function of RTSP watch dog
//
//Parameter:
//	param 		Always NULL
//Return:
//	always NULL
//
void * RTSPWatchdog_Thread(void * param)
{
    //func_info();
	RTSPConnection_t *conn;
	time_t now, bias;
	int i = 0;
	
	while (blWDIsRunning)
	{
	    Global_lock();
		_printAllConnections();
		time(&now);
		for(i = 0; i < AC_Count(g_ptRTSPServer->listRTSPConnection); i++)
		{
			conn = AC_Get(g_ptRTSPServer->listRTSPConnection, i);
			bias = now -conn->lastAccess;
			dbgprintf(0, "The lefttime %d is %d", i, bias);
			if (conn)
			{
				dbgprintf(0, "conn->commandID %d is %d", i, conn->commandID);
				switch (conn->commandID) 
				{
					case RTSP_CMD_SETUP:
						if (bias > WD_RTSP_TIMEOUT)
						{
							WDDisconnectRTSPConnection(conn);
						}
						break;
					case RTSP_CMD_TEARDOWN:
						if (bias > WD_RTSP_TIMEOUT)
						{
							WDDisconnectRTSPConnection(conn);
						}
						break;
					case RTSP_CMD_OPTIONS:
						if (bias > WD_SESSION_TIMEOUTSERVER)
						{
							WDDisconnectRTSPConnection(conn);
						}
						break;
					case RTSP_CMD_PLAY:
						if (bias > WD_SESSION_TIMEOUTSERVER)
						{
							#if 0
							playbias = now - conn->lastPlay;
							dbgprintf(0, "The playbias is %d, watchdog is %d", playbias, conn->WatchDogOn);
							if(playbias < 2 * WD_SESSION_TIMEOUT)
							{
								conn->WatchDogOn = false;
								break;
							}
							#endif
							WDDisconnectRTSPConnection(conn);
						}
						break;
					case RTSP_CMD_PAUSE:
						break;
					case RTSP_CMD_DESCRIBE:
						if (bias > WD_RTSP_TIMEOUT)
						{
							WDDisconnectRTSPConnection(conn);
						}
						break;
					case RTSP_CMD_RTSP:
						if (bias > WD_RTSP_TIMEOUT)
						{
							WDDisconnectRTSPConnection(conn);
						}
						break;
					case RTSP_CMD_SETPARAMETER:
						if (bias > WD_SESSION_TIMEOUTSERVER)
						{
							WDDisconnectRTSPConnection(conn);
						}
						break;
					default:
						dbgprintf(0, "The commandID is %d", conn->commandID);
						if (bias > WD_SESSION_TIMEOUTSERVER)
						{
							dbgprintf(0, "The commandID is %d and it will be closed", conn->commandID);
							WDDisconnectRTSPConnection(conn);
						}
						break;
				}
			}
		}
        Global_unlock();
		sleep(WD_SCAN_INTERVAL);
	}
	return NULL;
}

//Initialize watch dog
//
//Parameter:
//	
//Return:
// None
//
void InitRTSPWatchdog()
{
	blWDIsRunning = true;
	pthread_create(&wdThread, NULL, RTSPWatchdog_Thread, NULL);
	pthread_detach(wdThread);
}

//Release watch dog
//
//Parameter:
//	
//Return:
// None
//
void ReleaseRTSPWatchdog()
{
	blWDIsRunning = false;
}

